package com.patrick.api.starter.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.patrick.patrick.core.exception.OpenGlobalExceptionHandler;
import com.patrick.patrick.core.exception.OpenRestResponseErrorHandler;
import com.patrick.patrick.core.filter.XssFilter;
import com.patrick.patrick.core.gen.SnowflakeIdGenerator;
import com.patrick.patrick.core.health.DbHealthIndicator;
import com.patrick.patrick.core.mybatis.MyMetaObjectHandler;
import com.patrick.patrick.core.properties.OpenApiCoreProperties;
import com.patrick.patrick.core.security.OauthRestTemplate;
import com.patrick.patrick.core.security.OpenRefreshGateway;
import com.patrick.patrick.core.utils.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.cloud.bus.BusProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.client.RestTemplate;

/**
 * 默认配置类
 *
 * @author liuyadu
 */
@Slf4j
@Configuration
@EnableConfigurationProperties({OpenApiCoreProperties.class})
public class AutoConfiguration {


  /**
   * xss过滤
   * body缓存
   *
   * @return
   */
  @Bean
  public FilterRegistrationBean XssFilter() {
    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new XssFilter());
    log.info("XFilter [{}]", filterRegistrationBean);
    return filterRegistrationBean;
  }

  /**
   * 分页插件
   */
  @ConditionalOnMissingBean(PaginationInterceptor.class)
  @Bean
  public PaginationInterceptor paginationInterceptor() {
    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
    log.info("PaginationInterceptor [{}]", paginationInterceptor);
    return paginationInterceptor;
  }

  /**
   * 默认加密配置
   *
   * @return
   */
  @Bean
  @ConditionalOnMissingBean(BCryptPasswordEncoder.class)
  public BCryptPasswordEncoder bCryptPasswordEncoder() {
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    log.info("BCryptPasswordEncoder [{}]", encoder);
    return encoder;
  }


  /**
   * SpringContext
   *
   * @return
   */
  @Bean
  @ConditionalOnMissingBean(SpringContextHolder.class)
  public SpringContextHolder springContextHolder() {
    SpringContextHolder holder = new SpringContextHolder();
    log.info("SpringContextHolder [{}]", holder);
    return holder;
  }

  /**
   * 统一异常处理配置
   *
   * @return
   */
  @Bean
  @ConditionalOnMissingBean(OpenGlobalExceptionHandler.class)
  public OpenGlobalExceptionHandler exceptionHandler() {
    OpenGlobalExceptionHandler exceptionHandler = new OpenGlobalExceptionHandler();
    log.info("OpenGlobalExceptionHandler [{}]", exceptionHandler);
    return exceptionHandler;
  }

  /**
   * ID生成器配置
   *
   * @return
   */
  @Bean
  public SnowflakeIdGenerator snowflakeIdWorker() {
    SnowflakeIdGenerator snowflakeIdGenerator = new SnowflakeIdGenerator(0, 0);
    log.info("SnowflakeIdGenerator [{}]", snowflakeIdGenerator);
    return snowflakeIdGenerator;
  }


  /**
   * password方式RestTemplate
   *
   * @param openApiCoreProperties
   * @return
   */
  @Bean
  @ConditionalOnMissingBean(OauthRestTemplate.class)
  public OauthRestTemplate openRestTemplate(OpenApiCoreProperties openApiCoreProperties, BusProperties busProperties) {
    OauthRestTemplate restTemplate = new OauthRestTemplate(openApiCoreProperties);
    //设置自定义ErrorHandler
    restTemplate.setErrorHandler(new OpenRestResponseErrorHandler());
    log.info("OauthRestTemplate [{}]", restTemplate);
    return restTemplate;
  }

  /**
   * 全局广播、刷新路由
   *
   * @param busProperties
   * @param publisher
   * @return
   */
  @Bean
  @ConditionalOnMissingBean(OauthRestTemplate.class)
  public OpenRefreshGateway openRefreshGateway(BusProperties busProperties, ApplicationEventPublisher publisher) {
    OpenRefreshGateway refreshGateway = new OpenRefreshGateway(busProperties, publisher);
    log.info("OpenRefreshGateway [{}]", refreshGateway);
    return refreshGateway;
  }

  @Bean
  public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    //设置自定义ErrorHandler
    restTemplate.setErrorHandler(new OpenRestResponseErrorHandler());
    log.info("RestTemplate [{}]", restTemplate);
    return restTemplate;
  }

  @Bean
  @ConditionalOnMissingBean(DbHealthIndicator.class)
  public DbHealthIndicator dbHealthIndicator() {
    DbHealthIndicator dbHealthIndicator = new DbHealthIndicator();
    log.info("DbHealthIndicator [{}]", dbHealthIndicator);
    return dbHealthIndicator;
  }

  /**
   * 自动填充模型数据
   *
   * @return
   */
  @Bean
  @ConditionalOnMissingBean(MyMetaObjectHandler.class)
  public MyMetaObjectHandler modelMetaObjectHandler() {
    MyMetaObjectHandler metaObjectHandler = new MyMetaObjectHandler();
    log.info("MyMetaObjectHandler [{}]", metaObjectHandler);
    return metaObjectHandler;
  }
}
